package com.eqs.enterprisequestionnaire.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eqs.enterprisequestionnaire.mapper.RoleMapper;
import com.eqs.enterprisequestionnaire.mapper.UserMapper;
import com.eqs.enterprisequestionnaire.model.pojo.Role;
import com.eqs.enterprisequestionnaire.model.pojo.User;
import com.eqs.enterprisequestionnaire.result.R;
import com.eqs.enterprisequestionnaire.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
//import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    RoleMapper roleMapper;
    private Map<String, String> verificationCodes = new HashMap<>(); // For simplicity, use a Map to store verification codes
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    public void insertUser(User user)
    {
        user.setRegisteredTime(LocalDateTime.now());
        userMapper.insert(user);
    }
    public void registerUser(User user) {
        String password=user.getPassword();
      //  String salt = UUID.randomUUID().toString().replaceAll("-", ""); // 生成一个盐值，可以使用UUID等方式
        String salt=user.getUserName();
        String encryptedPassword = new SimpleHash("SHA-256", password, salt, 1024).toHex();

        user.setPassword(encryptedPassword);
        insertUser(user);
    }
    public User selectByUserName(String userName)
    {
        return userMapper.selectOne(getQueryWrapperUserByUserName(userName));
    }
    public QueryWrapper<User> getQueryWrapperUserByUserName(String userName){
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("user_name",userName);
        return queryWrapper;
    }
    public void updateUser(@NotNull User user)
    {
        // 获取现有用户信息
        User existingUser = selectById(user.getId());
        if (existingUser != null) {
            // 使用 BeanUtils.copyProperties 进行属性赋值
            BeanUtils.copyProperties(user, existingUser,getNullPropertyNames(user));
            existingUser.setUpdatedTime(LocalDateTime.now()); // 更新修改时间
            // 更新数据库中的用户信息
            userMapper.updateById(existingUser);
        } else {
            throw new RuntimeException("User not found");
        }
    }
    private User copyUser(User user) {
        User curUser = new User();
        // 使用 BeanUtils.copyProperties 进行属性赋值
        BeanUtils.copyProperties(user, curUser, getNullPropertyNames(user));
        return curUser;
    }

    // 获取所有值为 null 的属性名称
    @NotNull
    private String[] getNullPropertyNames(User source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    public void deleteUser(String userName){
        userMapper.delete(getQueryWrapperUserByUserName(userName));
    }

    @Override
    public boolean verifyCode(String email, String code) {
        return code.equals(verificationCodes.get(email));
    }

    public User selectById(Integer userId){
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",userId);
        return userMapper.selectOne(queryWrapper);
    }

    @Override
    public void updatePassword(Integer userId, String newPassword) {
        User currentUser=selectById(userId);
        //  String salt = UUID.randomUUID().toString().replaceAll("-", ""); // 生成一个盐值，可以使用UUID等方式
        String salt=currentUser.getUserName();
        String encryptedPassword = new SimpleHash("SHA-256", newPassword, salt, 1024).toHex();

        currentUser.setPassword(encryptedPassword);
        updateUser(currentUser);
    }

    public Integer selectIdByEmail(String email){
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("email",email);
        return userMapper.selectOne(queryWrapper).getId();
    }
    public String selectEmailById(Integer userId){
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",userId);
        return userMapper.selectOne(queryWrapper).getEmail();
    }
    @Override
    public void saveVerificationCode(String email, String code) {
        verificationCodes.put(email, code);
        //scheduler.schedule(() -> verificationCodes.remove(email), 300, TimeUnit.SECONDS);
    }

    @Override
    public Integer rightLevel(Integer userId) {
        Role role=getRoleByRoleName(userMapper.selectById(userId).getRoleName());
        return role.getRightLevel();
    }
    private Role getRoleByRoleName(String roleName){
        QueryWrapper<Role> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("role_name",roleName);
        return roleMapper.selectOne(queryWrapper);
    }

    public Integer calculateUserAge(Integer userId) {
        User user = userMapper.selectById(userId);
        if (user == null || user.getBirthday() == null) {
            throw new IllegalArgumentException("用户不存在或生日未设置");
        }
        Date birthday = user.getBirthday();
        LocalDate birthDate = new java.sql.Date(birthday.getTime()).toLocalDate();
        LocalDate currentDate = LocalDate.now();

        if (birthDate.isAfter(currentDate)) {
            throw new IllegalArgumentException("生日不能是未来的日期");
        }

        return Period.between(birthDate, currentDate).getYears();
    }

    @Override
    public Set<String> getUserRoles(Integer userId) {
        Set<String> roles = new HashSet<>();
        User user = userMapper.selectById(userId);
        if (user != null) {
            roles.add(user.getRoleName()); // 假设每个用户只对应一个角色名
        }
        return roles;
    }
    @Override
    public Set<String> getUserPermissions(Integer userId) {
        Set<String> permissions = new HashSet<>();
        String role_name=userMapper.selectById(userId).getRoleName();
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_name", role_name); // 根据你的表结构调整字段名称
        roleMapper.selectList(queryWrapper).forEach(role -> permissions.add(role.getRightLevel().toString()));
        return permissions;
    }

    public List<User> getAllUser(){
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        return userMapper.selectList(queryWrapper);
    }

    public List<User> getAllMaleUsers() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("gender", true); // assuming true represents male
        return userMapper.selectList(queryWrapper);
    }
    public List<User> getAllFemaleUsers() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("gender", false); // assuming false represents female
        return userMapper.selectList(queryWrapper);
    }
    public List<User> getUsersByCompany(String companyName) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("enterprise", companyName);
        return userMapper.selectList(queryWrapper);
    }

    public List<User> getUsersByAgeRange(Integer minAge, Integer maxAge) {
        LocalDate now = LocalDate.now();
        LocalDate minDate = now.minusYears(maxAge + 1).plusDays(1); // 最小年龄生日
        LocalDate maxDate = now.minusYears(minAge); // 最大年龄生日

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("birthday", Date.from(minDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
                Date.from(maxDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
        return userMapper.selectList(queryWrapper);
    }
    public User getCurUser(){
        return null;
    }
    public void refreshLogin(String userName,String password){
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        String encryptedPassword = new SimpleHash("SHA-256", password, userName, 1024).toHex();
        queryWrapper.eq("user_name",userName)
                .eq("password",encryptedPassword);
        if(userMapper.selectCount(queryWrapper)==1){
            User user=userMapper.selectOne(queryWrapper);
            user.setUpdatedTime(LocalDateTime.now());
            userMapper.updateById(user);
        }
    }
}